package com.gopay.bis.manager.bank.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.gopay.common.trace.GopayTracerType;
import com.gopay.common.trace.anotation.GopayTracer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.gopay.bis.dao.bankorder.BankBcdlOrderDAO;
import com.gopay.bis.dao.bankorder.BankOrderDAO;
import com.gopay.bis.dao.bankorder.BcdlSendBankLogDAO;
import com.gopay.bis.dao.bankorder.SendBankOrderDAO;
import com.gopay.bis.dao.bankorder.BcdlQueryBalanceDAO;
import com.gopay.bis.manager.bank.BankOrderManager;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BankRouteLog;
import com.gopay.common.domain.bank.BcdlSendBankLog;
import com.gopay.common.domain.bank.SendBankOrderCust;
import com.gopay.common.domain.bank.BcdlQueryBalance;
import com.gopay.common.domain.bis.BisBankBcdlOrder;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.event.CpsOrderEventSender;
import com.gopay.common.util.DateUtils;
import com.gopay.common.domain.bank.BankOrderDealLog;
import com.gopay.common.domain.bank.BankOrderExt;
import com.gopay.bis.dao.bankorder.BankOrderDealLogDAO;
import com.gopay.bis.dao.bankorder.BankOrderExtDAO;

/**
 * 银行流水MANAGER实现
 * 
 * @BankOrderDAOImpl.java
 * @author LEO
 * @2013-2-5 下午03:38:58 www.gopay.com.cn Inc.All rights reserved.
 */
@Service("bankOrderManager")
public class BankOrderManagerImpl implements BankOrderManager {

	@Resource(name = "bankOrderDAO")
	private BankOrderDAO bankOrderDAO;

	@Resource(name = "sendBankOrderDAO")
	private SendBankOrderDAO sendBankOrderDAO;

	@Resource(name = "bankBcdlOrderDAO")
	private BankBcdlOrderDAO bankBcdlOrderDAO;
	
	@Resource(name = "bcdlSendBankLogDAO")
	private BcdlSendBankLogDAO bcdlSendBankLogDAO;

	@Resource(name = "cpsOrderEventSender")
	private CpsOrderEventSender cpsOrderEventSender;

	@Resource(name = "bcdlQueryBalanceDAO")
	private BcdlQueryBalanceDAO bcdlQueryBalanceDAO;
	@Resource(name = "bankOrderDealLogDAO")
	private BankOrderDealLogDAO bankOrderDealLogDAO;
	@Resource(name = "bankOrderExtDAO")
	private BankOrderExtDAO bankOrderExtDAO;

	@GopayTracer(paramKey = "#bankOrder", tracerType = GopayTracerType.ORDER_TRACE)
	@Transactional
	public BankOrder addBankOrder(BankOrder bankOrder) {
		Date curDate = DateUtils.getSystemDate();

		bankOrder.setCreatedTs(curDate);
		bankOrder.setLastUpdTs(curDate);

		bankOrder = bankOrderDAO.save(bankOrder);

		// 发送订单更新事件
		CpsGenMainOrder cpsGenMainOrder = new CpsGenMainOrder();
		cpsGenMainOrder.setGopayOrderId(bankOrder.getOrderId());
		cpsOrderEventSender.sendSaveEvent(cpsGenMainOrder);

		return bankOrder;
	}

	@Transactional
	public SendBankOrderCust addSendBankOrder(SendBankOrderCust orderCust) {

		orderCust = sendBankOrderDAO.save(orderCust);

		return orderCust;
	}
    
    @Override
    public int updateBackFail(String orderId) {
        int result = bankOrderDAO.updateBackFail(orderId);
        return result;
    }

	/**
	 * 新增银行流水
	 * 
	 * @param bankOrder
	 * @return
	 */
	public BisBankBcdlOrder addBankBcdlOrder(BisBankBcdlOrder bankOrder) {
		Date curDate = DateUtils.getSystemDate();

		bankOrder.setCreated(curDate);
		bankOrder.setLastUpdTs(curDate);

		bankOrder = bankBcdlOrderDAO.save(bankOrder);

		return bankOrder;
	}

	public BisBankBcdlOrder getBankBcdlOrderById(String orderId) {

		BisBankBcdlOrder bankOrder = bankBcdlOrderDAO.findBankBcdlOrderById(orderId);

		return bankOrder;
	}

	@GopayTracer(paramKey = "#bankOrder", tracerType = GopayTracerType.ORDER_TRACE)
	@Transactional
	public void updateBankOrder(BankOrder bankOrder) {
		Date curDate = DateUtils.getSystemDate();

		bankOrder.setLastUpdTs(curDate);

		bankOrderDAO.update(bankOrder);

		// 发送订单更新事件
		CpsGenMainOrder cpsGenMainOrder = new CpsGenMainOrder();
		cpsGenMainOrder.setGopayOrderId(bankOrder.getOrderId());
		cpsOrderEventSender.sendUpdateEvent(cpsGenMainOrder);
	}

	public BankOrder getBankOrderById(String outOrderId) {
		BankOrder bankOrder = bankOrderDAO.find(BankOrder.class, outOrderId);
		return bankOrder;
	}

	public List<BankOrder> getBankOrdersByGopayOrderId(String orderId) {
		return bankOrderDAO.getBankOrdersByGopayOrderId(orderId);
	}

	@Override
	public int updateBackSuccess(String orderId) {
		int result = bankOrderDAO.updateBackSuccess(orderId);
		return result;
	}

	@Override
	public int updateBackVerifyFail(String outOrderId) {
		int result = bankOrderDAO.updateBackVerifyFail(outOrderId);
		return result;
	}

	@Override
	public int updateQueryBackSuccess(String orderId) {
		int result = bankOrderDAO.updateQueryBackSuccess(orderId);
		return result;
	}

	@Override
	public int updateQueryBackVerifyFail(String outOrderId) {
		int result = bankOrderDAO.updateQueryBackVerifyFail(outOrderId);
		return result;
	}

	@Override
	public int updateBpsSuccess(String orderId) {
		int result = bankOrderDAO.updateBpsCheckSuccess(orderId);

		return result;
	}

	@Override
	public int updateBpsFail(String orderId) {
		int result = bankOrderDAO.updateBpsCheckFail(orderId);
		return result;
	}

	@Override
	public int updateBpsOther(String orderId) {
		int result = bankOrderDAO.updateBpsCheckOther(orderId);

		return result;
	}

	/**
	 * 发送订单更新事件
	 * 
	 * @param gopayOrderId
	 */
	/*
	 * private void saveMqEventTimeoutLog(String gopayOrderId){ try{
	 * MqEventTimeoutLog eventLog=new MqEventTimeoutLog();
	 * eventLog.setType("02");
	 * 
	 * Map<String, Object> map = new HashMap<String, Object>();
	 * map.put("gopayOrderId", gopayOrderId);
	 * eventLog.setSnapshot(JSONObject.toJSONString(map,
	 * SerializerFeature.WriteClassName));
	 * 
	 * eventLog.setStat("01"); eventLog.setGopayOrderId(gopayOrderId);
	 * eventLog.setRemark1("银行订单表新增或更新"); eventLog.setCreatedTs(new Date());
	 * eventLog.setLastUpdTs(new Date());
	 * 
	 * mqEventTimeoutLogDAO.save(eventLog); }catch(Exception e){
	 * e.printStackTrace(); } }
	 */

	@Override
	public int updateInAcctFail(String orderId) {
		int result = bankOrderDAO.updateInAcctFail(orderId);

		return result;
	}

	@Override
	public int updateFrontBackTime(String orderId) {
		int result = bankOrderDAO.updateFrontBackTime(orderId);
		return result;
	}

	@Override
	public List<BcdlQueryBalance> getBcdlQueryByBankCodeAndOrderStatus(String bankCode, String queryOrderStatus) {
		return bcdlQueryBalanceDAO.getBcdlQueryByBankCodeAndOrderStatus(bankCode, queryOrderStatus);
	}

	public BcdlQueryBalance getBcdlQueryById(String orderId) {
		return bcdlQueryBalanceDAO.findBcdlQueryById(orderId);
	}

	@Override
	public BcdlQueryBalance addBcdlQueryOrder(BcdlQueryBalance queryOrder) {
		Date curDate = DateUtils.getSystemDate();
		queryOrder.setQueryCreatTime(curDate);
		queryOrder.setQueryLastTime(curDate);
		queryOrder = bcdlQueryBalanceDAO.save(queryOrder);
		return queryOrder;
	}

	@Override
	public void updateBcdlQueryOrder(BcdlQueryBalance queryOrder) {
		Date curDate = DateUtils.getSystemDate();
		queryOrder.setQueryLastTime(curDate);
		bcdlQueryBalanceDAO.update(queryOrder);
	}

	@Override
	public void addBankOrderDealLog(BankOrderDealLog bankOrderDealLog) {
		bankOrderDealLogDAO.save(bankOrderDealLog);
	}

	@Override
	public List<BankOrder> getBankOrdersByOriBankOrderId(String bankOrderId) {
		return bankOrderDAO.getBankOrdersByOriBankOrderId(bankOrderId);
	}

	@Override
	public int updateAmountError(String orderId) {
		int result = bankOrderDAO.updateAmountError(orderId);
		return result;
	}

	@Override
	public void addBankRouteLog(BankRouteLog bankRouteLog) {
		Date curDate = DateUtils.getSystemDate();
		bankRouteLog.setCreatedTs(curDate); // 增加时间戳
		bankOrderDAO.addBankRouteLog(bankRouteLog);
	}

	@Override
	public int updateQueryBackSuccess(BankOrder bankOrder, String bankOrderStatus) {
		int result = bankOrderDAO.updateQueryBackSuccess(bankOrder, bankOrderStatus);
		return result;
	}

	@Override
	public int updateQueryBackVerifyFail(BankOrder bankOrder) {
		int result = bankOrderDAO.updateQueryBackVerifyFail(bankOrder);
		return result;
	}

	@Override
	public int lock(BankOrder bankOrder) {
		int result = bankOrderDAO.lock(bankOrder);
		return result;
	}

	@Override
	public int unlock(BankOrder bankOrder) {
		int result = bankOrderDAO.unlock(bankOrder);
		return result;
	}

	@Override
	public int updateTotalCheckTimes(BankOrder bankOrder) {
		int result = bankOrderDAO.updateTotalCheckTimes(bankOrder);
		return result;
	}

	@Override
	public int updateFail(BankOrder bankOrder) {
		int result = bankOrderDAO.updateCheckFail(bankOrder);
		return result;
	}

	@Override
	public void updateBankBcdlOrder(BisBankBcdlOrder bcdlOrder) {
		Date curDate = DateUtils.getSystemDate();
		bcdlOrder.setLastUpdTs(curDate);
		bankBcdlOrderDAO.update(bcdlOrder);
	}

	@Transactional
	public void addBankOrderExt(BankOrderExt bankOrderExt) {
		bankOrderExtDAO.save(bankOrderExt);
	}

	@Override
	public BankOrderExt getBankOrderExtById(String bankOrderId) {
		BankOrderExt bankOrderExt = bankOrderExtDAO.find(BankOrderExt.class,bankOrderId);
		return bankOrderExt;
	}

	@Override
	public BcdlSendBankLog getBcdlSendLogById(String orderId) {
		return bcdlSendBankLogDAO.getBcdlSendLogById(orderId);
	}

	@Override
	public void deleteBcdlSendLog(BcdlSendBankLog bcdlSendBankLog) {
		bcdlSendBankLogDAO.deleteBcdlSendLog(bcdlSendBankLog);

	}

	/**
	 * 插入银企直连发往银行日志记录
	 * @param bankOrder
	 * zhoutong
	 */
	@Override
	public void saveBcdlSendBankLog(BankOrder bankOrder) {
		BcdlSendBankLog bcdlSendBankLog = new BcdlSendBankLog();
		bcdlSendBankLog.setGopayOrderId(bankOrder.getOrderId());
		bcdlSendBankLog.setCreateTime(new Date());
		bcdlSendBankLogDAO.save(bcdlSendBankLog);
	}

	@Override
	public void updateBackSuccess(String orderId, String bankId) {
		bankOrderDAO.updateBackSuccess(orderId, bankId);
	}
}
